home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2005 March / Macworld CD March 2005 - Marathon Trilogy.iso / Shareware World / iPod / iPodderX.sit / iPodderX / iPodderX.app / Contents / Resources / PiecePicker.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2005-01-07  |  8.0 KB  |  258 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.3)
  3.  
  4. from random import randrange, shuffle, choice
  5.  
  6. class PiecePicker:
  7.     
  8.     def __init__(self, numpieces, rarest_first_cutoff = 1):
  9.         self.rarest_first_cutoff = rarest_first_cutoff
  10.         self.numpieces = numpieces
  11.         self.interests = [
  12.             range(numpieces)]
  13.         self.pos_in_interests = range(numpieces)
  14.         self.numinterests = [
  15.             0] * numpieces
  16.         self.started = []
  17.         self.seedstarted = []
  18.         self.numgot = 0
  19.         self.scrambled = range(numpieces)
  20.         shuffle(self.scrambled)
  21.  
  22.     
  23.     def got_have(self, piece):
  24.         if self.numinterests[piece] is None:
  25.             return None
  26.         
  27.         numint = self.numinterests[piece]
  28.         if numint == len(self.interests) - 1:
  29.             self.interests.append([])
  30.         
  31.         self.numinterests[piece] += 1
  32.         self._shift_over(piece, self.interests[numint], self.interests[numint + 1])
  33.  
  34.     
  35.     def lost_have(self, piece):
  36.         if self.numinterests[piece] is None:
  37.             return None
  38.         
  39.         numint = self.numinterests[piece]
  40.         self.numinterests[piece] -= 1
  41.         self._shift_over(piece, self.interests[numint], self.interests[numint - 1])
  42.  
  43.     
  44.     def _shift_over(self, piece, l1, l2):
  45.         p = self.pos_in_interests[piece]
  46.         l1[p] = l1[-1]
  47.         self.pos_in_interests[l1[-1]] = p
  48.         del l1[-1]
  49.         newp = randrange(len(l2) + 1)
  50.         if newp == len(l2):
  51.             self.pos_in_interests[piece] = len(l2)
  52.             l2.append(piece)
  53.         else:
  54.             old = l2[newp]
  55.             self.pos_in_interests[old] = len(l2)
  56.             l2.append(old)
  57.             l2[newp] = piece
  58.             self.pos_in_interests[piece] = newp
  59.  
  60.     
  61.     def requested(self, piece, seed = False):
  62.         if piece not in self.started:
  63.             self.started.append(piece)
  64.         
  65.         if seed and piece not in self.seedstarted:
  66.             self.seedstarted.append(piece)
  67.         
  68.  
  69.     
  70.     def complete(self, piece):
  71.         if not self.numinterests[piece] is not None:
  72.             raise AssertionError
  73.         self.numgot += 1
  74.         l = self.interests[self.numinterests[piece]]
  75.         p = self.pos_in_interests[piece]
  76.         l[p] = l[-1]
  77.         self.pos_in_interests[l[-1]] = p
  78.         del l[-1]
  79.         self.numinterests[piece] = None
  80.         
  81.         try:
  82.             self.started.remove(piece)
  83.             self.seedstarted.remove(piece)
  84.         except ValueError:
  85.             self
  86.             self
  87.         except:
  88.             self
  89.  
  90.  
  91.     
  92.     def next(self, havefunc, seed = False):
  93.         bests = None
  94.         bestnum = 2 ** 30
  95.         if seed:
  96.             s = self.seedstarted
  97.         else:
  98.             s = self.started
  99.         for i in s:
  100.             if havefunc(i):
  101.                 if self.numinterests[i] < bestnum:
  102.                     bests = [
  103.                         i]
  104.                     bestnum = self.numinterests[i]
  105.                 elif self.numinterests[i] == bestnum:
  106.                     bests.append(i)
  107.                 
  108.             self.numinterests[i] < bestnum
  109.         
  110.         if bests:
  111.             return choice(bests)
  112.         
  113.         if self.numgot < self.rarest_first_cutoff:
  114.             for i in self.scrambled:
  115.                 if havefunc(i):
  116.                     return i
  117.                     continue
  118.             
  119.             return None
  120.         
  121.         for i in xrange(1, min(bestnum, len(self.interests))):
  122.             for j in self.interests[i]:
  123.                 if havefunc(j):
  124.                     return j
  125.                     continue
  126.             
  127.         
  128.         return None
  129.  
  130.     
  131.     def am_I_complete(self):
  132.         return self.numgot == self.numpieces
  133.  
  134.     
  135.     def bump(self, piece):
  136.         l = self.interests[self.numinterests[piece]]
  137.         pos = self.pos_in_interests[piece]
  138.         del l[pos]
  139.         l.append(piece)
  140.         for i in range(pos, len(l)):
  141.             self.pos_in_interests[l[i]] = i
  142.         
  143.  
  144.  
  145.  
  146. def test_requested():
  147.     p = PiecePicker(9)
  148.     p.complete(8)
  149.     p.got_have(0)
  150.     p.got_have(2)
  151.     p.got_have(4)
  152.     p.got_have(6)
  153.     p.requested(1)
  154.     p.requested(1)
  155.     p.requested(3)
  156.     p.requested(0)
  157.     p.requested(6)
  158.     v = _pull(p)
  159.     if not v[:2] == [
  160.         1,
  161.         3] or v[:2] == [
  162.         3,
  163.         1]:
  164.         raise AssertionError
  165.     if not v[2:4] == [
  166.         0,
  167.         6] or v[2:4] == [
  168.         6,
  169.         0]:
  170.         raise AssertionError
  171.     if not v[4:] == [
  172.         2,
  173.         4] or v[4:] == [
  174.         4,
  175.         2]:
  176.         raise AssertionError
  177.  
  178.  
  179. def test_change_interest():
  180.     p = PiecePicker(9)
  181.     p.complete(8)
  182.     p.got_have(0)
  183.     p.got_have(2)
  184.     p.got_have(4)
  185.     p.got_have(6)
  186.     p.lost_have(2)
  187.     p.lost_have(6)
  188.     v = _pull(p)
  189.     if not v == [
  190.         0,
  191.         4] or v == [
  192.         4,
  193.         0]:
  194.         raise AssertionError
  195.  
  196.  
  197. def test_change_interest2():
  198.     p = PiecePicker(9)
  199.     p.complete(8)
  200.     p.got_have(0)
  201.     p.got_have(2)
  202.     p.got_have(4)
  203.     p.got_have(6)
  204.     p.lost_have(2)
  205.     p.lost_have(6)
  206.     v = _pull(p)
  207.     if not v == [
  208.         0,
  209.         4] or v == [
  210.         4,
  211.         0]:
  212.         raise AssertionError
  213.  
  214.  
  215. def test_complete():
  216.     p = PiecePicker(1)
  217.     p.got_have(0)
  218.     p.complete(0)
  219.     if not _pull(p) == []:
  220.         raise AssertionError
  221.     p.got_have(0)
  222.     p.lost_have(0)
  223.  
  224.  
  225. def test_rarer_in_started_takes_priority():
  226.     p = PiecePicker(3)
  227.     p.complete(2)
  228.     p.requested(0)
  229.     p.requested(1)
  230.     p.got_have(1)
  231.     p.got_have(0)
  232.     p.got_have(0)
  233.     if not _pull(p) == [
  234.         1,
  235.         0]:
  236.         raise AssertionError
  237.  
  238.  
  239. def test_zero():
  240.     if not _pull(PiecePicker(0)) == []:
  241.         raise AssertionError
  242.  
  243.  
  244. def _pull(pp):
  245.     r = []
  246.     
  247.     def want(p, r = r):
  248.         return p not in r
  249.  
  250.     while True:
  251.         n = pp.next(want)
  252.         if n is None:
  253.             break
  254.         
  255.         r.append(n)
  256.     return r
  257.  
  258.